package com.java.multipledatasource.thread;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/**
 * @author hu
 * @version 1.0
 * @date 2021/1/16 0016 下午 7:59
 * @description 写一个固定容量的同步容器， 拥有put 和 get 方法，以及 getCount 方法，
 *               能够支持2个生产者线程以及10个消费者线程的阻塞调用
 */
public class Thread4<T> {
    final private List<T> list = new LinkedList<>();
    final private int MAX = 10;
    private int count = 0;

    public  synchronized  void put(T t) {
        while (list.size() == MAX) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        list.add(t);
        ++count;
        this.notifyAll();
    }

    public synchronized T get() {
        while (list.size() == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        T t = list.get(0);
        list.remove(0);
        count--;
        this.notifyAll();
        return  t;
    }
    public int getCount() {
        return this.count;
    }

    public static void main(String[] args) {
        Thread4<String> t4 = new Thread4<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int i1 = 0; i1 < 5; i1++) {
                    System.out.println(Thread.currentThread().getName() + "  " + t4.get() + "    " + t4.getCount());
                }
            }, "consumer" + i).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                for (int i1 = 0; i1 < 15; i1++) {
                    t4.put( Thread.currentThread().getName() +  new Random().toString());
                }
            }, "product" + i).start();
        }
    }
}
